<!DOCTYPE HTML>
<html lang="zh-CN">


<head>
    <!-- hexo-inject:begin --><!-- hexo-inject:end --><meta charset="utf-8">
    <meta name="keywords" content="浏览器的相关的一些知识, HTML,CSS,JavaScript,JQuery,React,Vue.js等">
    <meta name="description" content="别做一个Vue api调用师">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta name="renderer" content="webkit|ie-stand|ie-comp">
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
    <!-- Global site tag (gtag.js) - Google Analytics -->


    <title>浏览器的相关的一些知识 | zihao blog</title>
    <link rel="icon" type="image/png" href="/pride-blog/favicon.png">

    <link rel="stylesheet" type="text/css" href="/pride-blog/libs/awesome/css/all.css">
    <link rel="stylesheet" type="text/css" href="/pride-blog/libs/materialize/materialize.min.css">
    <link rel="stylesheet" type="text/css" href="/pride-blog/libs/aos/aos.css">
    <link rel="stylesheet" type="text/css" href="/pride-blog/libs/animate/animate.min.css">
    <link rel="stylesheet" type="text/css" href="/pride-blog/libs/lightGallery/css/lightgallery.min.css">
    <link rel="stylesheet" type="text/css" href="/pride-blog/css/matery.css">
    <link rel="stylesheet" type="text/css" href="/pride-blog/css/my.css">

    <script src="/pride-blog/libs/jquery/jquery.min.js"></script>

<meta name="generator" content="Hexo 5.3.0"><link rel="stylesheet" href="/pride-blog/css/prism-tomorrow.css" type="text/css"><!-- hexo-inject:begin --><!-- hexo-inject:end --></head>




<body>
    <!-- hexo-inject:begin --><!-- hexo-inject:end --><header class="navbar-fixed">
    <nav id="headNav" class="bg-color nav-transparent">
        <div id="navContainer" class="nav-wrapper container">
            <div class="brand-logo">
                <a href="/pride-blog/" class="waves-effect waves-light">
                    
                    <img src="/pride-blog/medias/logo.png" class="logo-img" alt="LOGO">
                    
                    <span class="logo-span">zihao blog</span>
                </a>
            </div>
            

<a href="#" data-target="mobile-nav" class="sidenav-trigger button-collapse"><i class="fas fa-bars"></i></a>
<ul class="right nav-menu">
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/pride-blog/" class="waves-effect waves-light">
      
      <i class="fas fa-home" style="zoom: 0.6;"></i>
      
      <span>首页</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/pride-blog/categories/CSS/" class="waves-effect waves-light">
      
      <i class="fas fa-bookmark" style="zoom: 0.6;"></i>
      
      <span>分类</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/pride-blog/archives" class="waves-effect waves-light">
      
      <i class="fas fa-archive" style="zoom: 0.6;"></i>
      
      <span>归档</span>
    </a>
    
  </li>
  
  <li>
    <a href="#searchModal" class="modal-trigger waves-effect waves-light">
      <i id="searchIcon" class="fas fa-search" title="搜索" style="zoom: 0.85;"></i>
    </a>
  </li>
</ul>


<div id="mobile-nav" class="side-nav sidenav">

    <div class="mobile-head bg-color">
        
        <img src="/pride-blog/medias/logo.png" class="logo-img circle responsive-img">
        
        <div class="logo-name">zihao blog</div>
        <div class="logo-desc">
            
            别做一个Vue api调用师
            
        </div>
    </div>

    

    <ul class="menu-list mobile-menu-list">
        
        <li class="m-nav-item">
	  
		<a href="/pride-blog/" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-home"></i>
			
			首页
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/pride-blog/categories/CSS/" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-bookmark"></i>
			
			分类
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/pride-blog/archives" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-archive"></i>
			
			归档
		</a>
          
        </li>
        
        
    </ul>
</div>


        </div>

        
    </nav>

</header>

    



<div class="bg-cover pd-header post-cover" style="background-image: url('/pride-blog/medias/featureimages/0.jpg')">
    <div class="container" style="right: 0px;left: 0px;">
        <div class="row">
            <div class="col s12 m12 l12">
                <div class="brand">
                    <h1 class="description center-align post-title">浏览器的相关的一些知识</h1>
                </div>
            </div>
        </div>
    </div>
</div>




<main class="post-container content">

    
    <link rel="stylesheet" href="/pride-blog/libs/tocbot/tocbot.css">
<style>
    #articleContent h1::before,
    #articleContent h2::before,
    #articleContent h3::before,
    #articleContent h4::before,
    #articleContent h5::before,
    #articleContent h6::before {
        display: block;
        content: " ";
        height: 100px;
        margin-top: -100px;
        visibility: hidden;
    }

    #articleContent :focus {
        outline: none;
    }

    .toc-fixed {
        position: fixed;
        top: 64px;
    }

    .toc-widget {
        width: 345px;
        padding-left: 20px;
    }

    .toc-widget .toc-title {
        padding: 35px 0 15px 17px;
        font-size: 1.5rem;
        font-weight: bold;
        line-height: 1.5rem;
    }

    .toc-widget ol {
        padding: 0;
        list-style: none;
    }

    #toc-content {
        padding-bottom: 30px;
        overflow: auto;
    }

    #toc-content ol {
        padding-left: 10px;
    }

    #toc-content ol li {
        padding-left: 10px;
    }

    #toc-content .toc-link:hover {
        color: #42b983;
        font-weight: 700;
        text-decoration: underline;
    }

    #toc-content .toc-link::before {
        background-color: transparent;
        max-height: 25px;

        position: absolute;
        right: 23.5vw;
        display: block;
    }

    #toc-content .is-active-link {
        color: #42b983;
    }

    #floating-toc-btn {
        position: fixed;
        right: 15px;
        bottom: 76px;
        padding-top: 15px;
        margin-bottom: 0;
        z-index: 998;
    }

    #floating-toc-btn .btn-floating {
        width: 48px;
        height: 48px;
    }

    #floating-toc-btn .btn-floating i {
        line-height: 48px;
        font-size: 1.4rem;
    }
</style>
<div class="row">
    <div id="main-content" class="col s12 m12 l9">
        <!-- 文章内容详情 -->
<div id="artDetail">
    <div class="card">
        <div class="card-content article-info">
            <div class="row tag-cate">
                <div class="col s7">
                    
                    <div class="article-tag">
                        
                            <a href="/pride-blog/tags/%E6%AF%8F%E5%A4%A9%E4%B8%80%E4%B8%AA%E7%A6%BB%E8%81%8C%E5%B0%8F%E6%8A%80%E5%B7%A7/">
                                <span class="chip bg-color">每天一个离职小技巧</span>
                            </a>
                        
                    </div>
                    
                </div>
                <div class="col s5 right-align">
                    
                    <div class="post-cate">
                        <i class="fas fa-bookmark fa-fw icon-category"></i>
                        
                            <a href="/pride-blog/categories/%E6%AF%8F%E5%A4%A9%E4%B8%80%E4%B8%AA%E7%A6%BB%E8%81%8C%E5%B0%8F%E6%8A%80%E5%B7%A7/" class="post-category">
                                每天一个离职小技巧
                            </a>
                        
                    </div>
                    
                </div>
            </div>

            <div class="post-info">
                
                <div class="post-date info-break-policy">
                    <i class="far fa-calendar-minus fa-fw"></i>发布日期:&nbsp;&nbsp;
                    2021-08-04
                </div>
                

                

                

                

                
            </div>
        </div>
        <hr class="clearfix">

        

        

        <div class="card-content article-card-content">
            <div id="articleContent">
                <h4 id="1-HTTP与HTTPS的区别？"><a href="#1-HTTP与HTTPS的区别？" class="headerlink" title="1.HTTP与HTTPS的区别？"></a>1.<code>HTTP</code>与<code>HTTPS</code>的区别？</h4><p>1.<code>HTTP</code> 的 URL 以 http:// 开头，而 HTTPS 的 URL 以 https:// 开头</p>
<p>2.<code>HTTP</code> 是不安全的，而 HTTPS 是安全的</p>
<p>3.<code>HTTP</code> 标准端口是 80 ，而 HTTPS 的标准端口是 443</p>
<p>4.在<code>OSI</code> 网络模型中，HTTP 工作于应用层，而 HTTPS 的安全传输机制工作在传输层</p>
<p>5.<code>HTTP</code> 无法加密，而 HTTPS 对传输的数据进行加密</p>
<p>6.<code>HTTP</code>无需证书，而 HTTPS 需要 CA 机构 wosign 的颁发的 SSL 证书</p>
<h4 id="2-Http的状态码有哪些"><a href="#2-Http的状态码有哪些" class="headerlink" title="2.Http的状态码有哪些?"></a>2.<code>Http</code>的状态码有哪些?</h4><ul>
<li><code>200</code>：请求被正常处理</li>
<li><code>204</code>：请求被受理但没有资源可以返回</li>
<li><code>206</code>：客户端只是请求资源的一部分，服务器只对请求的部分资源执行 GET 方法，相应报文中通过 Content-Range 指定范围的资源。</li>
<li><code>301</code>：永久性重定向</li>
<li><code>302</code>：临时重定向</li>
<li><code>303</code>：与 302 状态码有相似功能，只是它希望客户端在请求一个 URI 的时候，能通过 GET 方法重定向到另一个 URI 上</li>
<li><code>304</code>：发送附带条件的请求时，条件不满足时返回，与重定向无关</li>
<li><code>307</code>：临时重定向，与 302 类似，只是强制要求使用 POST 方法</li>
<li><code>400</code>：请求报文语法有误，服务器无法识别</li>
<li><code>401</code>：请求需要认证</li>
<li><code>403</code>：请求的对应资源禁止被访问</li>
<li><code>404</code>：服务器无法找到对应资源</li>
<li><code>500</code>：服务器内部错误</li>
<li><code>503</code>：服务器超过最大负荷</li>
</ul>
<h4 id="3-一次完整的HTTP事务是怎样一个过程？"><a href="#3-一次完整的HTTP事务是怎样一个过程？" class="headerlink" title="3.一次完整的HTTP事务是怎样一个过程？"></a>3.一次完整的<code>HTTP</code>事务是怎样一个过程？</h4><p>1）域名解析</p>
<p>2） 发起<code>TCP</code>的 3 次握手</p>
<p>3） 建立<code>TCP</code>连接后发起<code>http</code>请求</p>
<p>4） 服务器响应<code>http</code>请求，浏览器得到 html 代码</p>
<p>5） 浏览器解析<code>html</code>代码，并请求<code>html</code>代码中的资源（如<code>js</code>、<code>css</code>、<code>图片</code>等）</p>
<p>6） 浏览器对页面进行渲染呈现给用户</p>
<h4 id="4-说说304缓存的原理"><a href="#4-说说304缓存的原理" class="headerlink" title="4.说说304缓存的原理?"></a>4.说说<code>304</code>缓存的原理?</h4><p>1.服务器首先产生<code>ETag</code>，服务器可在稍后使用它来判断页面是否已经被修改。本质上，客户端通过将该记号传回服务器要求服务器验证其（客户端）缓存</p>
<p>2.<code>304</code>是<code>HTTP</code>状态码，服务器用来标识这个文件没修改，不返回内容，浏览器在接收到个状态码后，会使用浏览器已缓存的文件</p>
<p>3.客户端请求一个页面（<code>A</code>）。 服务器返回页面 A，并在给 A 加上一个<code>ETag</code>。 客户端展现该页面，并将页面连同<code>ETag</code>一起缓存。 客户再次请求页面 A，并将上次请求时服务器返回的<code>ETag</code>一起传递给服务器。 服务器检查该 ETag，并判断出该页面自上次客户端请求之后还未被修改，直接返回响应<code>304</code>（未修改——<code>Not Modified</code>）和一个空的响应体</p>
<h4 id="5-为什么HTTPS安全"><a href="#5-为什么HTTPS安全" class="headerlink" title="5.为什么HTTPS安全?"></a>5.为什么<code>HTTPS</code>安全?</h4><p>因为网络请求需要中间有很多的服务器路由器的转发。中间的节点都可能篡改信息，而如果使用<code>HTTPS</code>，密钥在你和终点站才有。</p>
<p><code>https</code>之所以比<code>http</code>安全，是因为他利用<code>ssl/tls</code>协议传输。</p>
<p>它包含证书，卸载，流量转发，负载均衡，页面适配，浏览器适配，<code>refer</code>传递等。保障了传输过程的安全性</p>
<h4 id="6-说说网络分层里七层模型是哪七层"><a href="#6-说说网络分层里七层模型是哪七层" class="headerlink" title="6.说说网络分层里七层模型是哪七层?"></a>6.说说网络分层里七层模型是哪七层?</h4><p><code>应用层</code>：允许访问 OSI 环境的手段</p>
<p><code>表示层</code>：对数据进行翻译、加密和压缩</p>
<p><code>会话层</code>：建立、管理和终止会话</p>
<p><code>传输层</code>：提供端到端的可靠报文传递和错误恢复</p>
<p><code>网络层</code>：负责数据包从源到宿的传递和网际互连</p>
<p><code>物理层</code>：通过媒介传输比特,确定机械及电气规范</p>
<h4 id="7-一个页面从输入-URL-到页面加载显示完成，这个过程中都发生了什么"><a href="#7-一个页面从输入-URL-到页面加载显示完成，这个过程中都发生了什么" class="headerlink" title="7.一个页面从输入 URL 到页面加载显示完成，这个过程中都发生了什么?"></a>7.一个页面从输入 <code>URL</code> 到页面加载显示完成，这个过程中都发生了什么?</h4><p><code>01</code>.浏览器查找域名对应的 IP 地址(DNS 查询：浏览器缓存-&gt;系统缓存-&gt;路由器缓存-&gt;ISP DNS 缓存-&gt;根域名服务器)</p>
<p><code>02</code>.浏览器向 Web 服务器发送一个 HTTP 请求（TCP 三次握手）</p>
<p><code>03</code>.服务器 301 重定向（从 <a target="_blank" rel="noopener" href="http://example.com/">http://example.com</a> 重定向到 <a target="_blank" rel="noopener" href="http://www.example.com)/">http://www.example.com）</a></p>
<p><code>04</code>.浏览器跟踪重定向地址，请求另一个带 www 的网址</p>
<p><code>05</code>.服务器处理请求（通过路由读取资源）</p>
<p><code>06</code>.服务器返回一个 HTTP 响应（报头中把 Content-type 设置为 ‘text/html’）</p>
<p><code>07</code>.浏览器进 DOM 树构建</p>
<p><code>08</code>.浏览器发送请求获取嵌在 HTML 中的资源（如图片、音频、视频、CSS、JS 等）</p>
<p><code>09</code>.浏览器显示完成页面</p>
<p><code>10</code>.浏览器发送异步请求</p>
<h4 id="8-介绍下http缓存"><a href="#8-介绍下http缓存" class="headerlink" title="8.介绍下http缓存!"></a>8.介绍下<code>http</code>缓存!</h4><h4 id="缓存介绍："><a href="#缓存介绍：" class="headerlink" title="缓存介绍："></a>缓存介绍：</h4><p>缓存就是让同一份资源不再发起请求，降低网络压力和资源数量，从而让网页加载更快。<br>网络请求不稳定加剧了网页加载的不稳定性，所以需要缓存。<br>一般来说，js、css、img 等静态资源可以被缓存</p>
<h4 id="http-缓存策略："><a href="#http-缓存策略：" class="headerlink" title="http 缓存策略："></a>http 缓存策略：</h4><h6 id="强制缓存（Cache-Control）"><a href="#强制缓存（Cache-Control）" class="headerlink" title="强制缓存（Cache-Control）"></a>强制缓存（Cache-Control）</h6><p><img src="https://img-blog.csdnimg.cn/20200620174738851.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNTY2NTQ3,size_16,color_FFFFFF,t_70#pic_center"></p>
<p><code>cache-control</code>在<code>response-headers</code>中，用于对缓存资源的控制，该属性可以控制强制缓存的逻辑，例如：<code>Cache-Control: max-age=31536000</code>(单位是秒)。<br>当再次请求时，先检查过期与否，若没有过期，则直接从缓存里拿数据，反之再次向服务器请求<br>Cache-Control 的值：</p>
<ul>
<li>max-age （缓存的内容将在 xxx 秒后失效）</li>
<li>no-cache（不用本地缓存）</li>
<li>no-store（不用本地和服务端的缓存）</li>
</ul>
<p>在现代浏览器中兼容<code>Expires</code>和<code>Cache-Control</code>，不过优先使用<code>Cache-Control</code></p>
<h6 id="协商缓存（对比缓存）"><a href="#协商缓存（对比缓存）" class="headerlink" title="协商缓存（对比缓存）"></a>协商缓存（对比缓存）</h6><p><img src="https://img-blog.csdnimg.cn/20200620174705697.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNTY2NTQ3,size_16,color_FFFFFF,t_70#pic_center"></p>
<p>协商缓存是服务端缓存策略（服务端判断该资源能否被缓存，而不是资源缓存在服务端），判断依据是客户端和服务端的资源标识是否一样，若一样则返回<code>304</code>，否则返回<code>200</code>和最新的资源、资源标识(资源标识在<code>response headers</code>中)</p>
<h4 id="资源标识："><a href="#资源标识：" class="headerlink" title="资源标识："></a>资源标识：</h4><p><code>Last-Modified</code>（客户端再次请求时，<code>request headers</code>带着<code>if-Modified-Since</code>） 资源的最后修改时间</p>
<p><code>Etag</code> 资源的唯一标识（客户端再次请求时，<code>request headers</code>带着<code>if-None-Match</code>）（一个字符串）<br>当两种资源标识共同存在时，优先使用<code>Etag</code>，因为<code>Last-Modified</code>只能精确到秒级，而<code>Etag</code>唯一</p>
<p><img src="https://img-blog.csdnimg.cn/20200620174638203.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNTY2NTQ3,size_16,color_FFFFFF,t_70#pic_center"></p>
<ul>
<li>刷新操作方式，对缓存的影响：</li>
<li>正常操作：地址栏输入 URL，跳转链接，前进后退等，强制缓存和协商缓存均有效</li>
<li>手动刷新：F5，点击刷新按钮，右键菜单刷新，强制缓存失效，协商缓存有效</li>
<li>强制刷新：ctrl+F5，强制缓存和协商缓存均无效</li>
</ul>
<h5 id="9-TCP-为什么是三次握手，而不是两次或四次？"><a href="#9-TCP-为什么是三次握手，而不是两次或四次？" class="headerlink" title="9.TCP 为什么是三次握手，而不是两次或四次？"></a>9.<code>TCP</code> 为什么是三次握手，而不是两次或四次？</h5><p><code>TCP</code> 为什么是三次握手，而不是两次或四次？</p>
<blockquote>
<p>两次不安全，四次浪费资源。</p>
</blockquote>
<p>三次握手，可以防止失效的连接请求报文段被服务端接收，从而产生错误。</p>
<p>所谓失效的连接请求，是指客户端向服务端发送的连接请求丢失，客户端等待应答超时后就会再次发送连接请求，此时，上一个连接请求就是『失效的』。</p>
<p>这样一个失效的连接请求，在网络中滞留许久后，到达服务端，服务端误以为是客户端再次发出的一个新的连接请求。</p>
<p>于是就向<code>client</code>发出确认报文段，同意建立连接。</p>
<p>假设不采用“三次握手”，那么只要服务端发出确认，新的连接就建立了。由于现在客户端并没有发出建立连接的请求，因此不会理睬服务端的确认，也不会向服务端发送数据。</p>
<p>但服务端却以为新的运输连接已经建立，并一直等待客户端发来数据。这样，服务端的很多资源就白白浪费掉了。</p>
<p>采用“<code>三次握手</code>”的办法可以防止上述现象发生。例如刚才那种情况，客户端不会向服务端发出确认。服务端由于收不到确认，就知道客户端并没有要求建立连接。。这样就避免服务端一直等待，浪费资源。</p>
<h5 id="10-HTTP-中-GET-与-POST-的区别"><a href="#10-HTTP-中-GET-与-POST-的区别" class="headerlink" title="10.HTTP 中 GET 与 POST 的区别"></a>10.<code>HTTP</code> 中 GET 与 <code>POST</code> 的区别</h5><p><code>GET</code>和<code>POST</code>是<code>HTTP</code>请求的两种基本方法，要说它们的区别，接触过<code>WEB</code>开发的人都能说出一二。</p>
<p>最直观的区别就是<code>GET</code>把参数包含在<code>URL</code>中,<code>POST</code>通过<code>request body</code>传递参数。</p>
<p>你可能自己写过无数个 GET 和 POST 请求，或者已经看过很多权威网站总结出的他们的区别，你非常清楚知道什么时候该用什么。</p>
<p>当你在面试中被问到这个问题，你的内心充满了自信和喜悦。</p>
<p><code>1</code>.GET 在浏览器回退时是无害的，而 POST 会再次提交请求。</p>
<p><code>2</code>.GET 产生的 URL 地址可以被 Bookmark，而 POST 不可以</p>
<p><code>3</code>.GET 请求会被浏览器主动 cache，而 POST 不会，除非手动设置。</p>
<p><code>4</code>.GET 请求只能进行 url 编码，而 POST 支持多种编码方式。</p>
<p><code>5</code>.GET 请求参数会被完整保留在浏览器历史记录里，而 POST 中的参数不会被保留。</p>
<p><code>6</code>.GET 请求在 URL 中传送的参数是有长度限制的，而 POST 么有。</p>
<p><code>7</code>.对参数的数据类型，GET 只接受 ASCII 字符，而 POST 没有限制。</p>
<p><code>8</code>.GET 比 POST 更不安全，因为参数直接暴露在 URL 上，所以不能用来传递敏感信息。</p>
<p><code>9</code>.GET 参数通过 URL 传递，POST 放在 Request body 中。</p>
<h4 id="11-从输入URL到页面加载发生了什么？"><a href="#11-从输入URL到页面加载发生了什么？" class="headerlink" title="11.从输入URL到页面加载发生了什么？"></a>11.从输入<code>URL</code>到页面加载发生了什么？</h4><p>这个问题有没有觉得很眼熟，相信很多人在面试中都遇到过，这是一道非常非常经典的面试题！面试官喜欢问，是因为这道题真的可以考察很多方面的知识。</p>
<p><code>1、</code>浏览器的地址栏输入 URL 并按下回车。</p>
<p><code>2、</code>浏览器查找当前 URL 是否存在缓存，并比较缓存是否过期。</p>
<p><code>3、</code>DNS 解析 URL 对应的 IP。</p>
<p><code>4、</code>根据 IP 建立 TCP 连接（三次握手）。</p>
<p><code>5、</code>HTTP 发起请求。</p>
<p><code>6、</code>服务器处理请求，浏览器接收 HTTP 响应。</p>
<p><code>7、</code>渲染页面，构建 DOM 树。</p>
<p><code>8、</code>关闭 TCP 连接（四次挥手）。</p>
<p>如下流程图:<br><img src="https://yangyunhaiimagesoss.oss-cn-shanghai.aliyuncs.com/2011091813_1604916792752.png"></p>
<h4 id="12-浏览器缓存原理是什么？"><a href="#12-浏览器缓存原理是什么？" class="headerlink" title="12.浏览器缓存原理是什么？"></a>12.浏览器缓存原理是什么？</h4><h3 id="什么是缓存？"><a href="#什么是缓存？" class="headerlink" title="什么是缓存？"></a>什么是缓存？</h3><p>浏览器缓存(Brower Caching)是浏览器对之前请求过的文件进行缓存，以便下一次访问时重复使用，节省带宽，提高访问速度，降低服务器压力</p>
<p>http 缓存机制主要在 http 响应头中设定，响应头中相关字段为 Expires、Cache-Control、Last-Modified、Etag。</p>
<p>HTTP 1.0 协议中的。简而言之，就是告诉浏览器在约定的这个时间前，可以直接从缓存中获取资源（representations），而无需跑到服务器去获取。</p>
<p>网站访问速度对一个网站来说是非常重要的，访问慢会流失用户，访问快会大大的提高用户体验。</p>
<p>浏览器缓存大概有两种，<code>200 OK (from memory/disk cache)</code>和<code>304 Not Modified</code>各有各的优势，把他们发挥好可以大大的提升访问速度</p>
<h3 id="强缓存-200-OK-from-memory-disk-cache"><a href="#强缓存-200-OK-from-memory-disk-cache" class="headerlink" title="强缓存 200 OK (from memory/disk cache)"></a>强缓存 200 OK (from memory/disk cache)</h3><p>这种缓存方式已经很普遍，大部分网站的静态文件都采用了，200 OK (from memory cache)或者 200 OK (from disk cache)都是直接读取客户端的缓存，无需再请求服务器。一般是在 Apache 或者 Nginx 里设置，比如 Nginx 配置里会有类似这样的配置：</p>
<pre><code> location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
 &#123;
     expires      30d;
 &#125;
 location ~ .*\.(js|css)?$
 &#123;
     expires      12h;
 &#125;</code></pre>
<p>这样就可以给静态文件缓存了，在有效期内，浏览器会直接读取客户端的缓存，而不用再请求服务器，除非用户清除了缓存或者使用 Ctrl+F5 强制刷新了页面。</p>
<p><img src="https://yangyunhaiimagesoss.oss-cn-shanghai.aliyuncs.com/2011091742_1604914954114.gif"></p>
<p>比如上图，是已经缓存过了的，至于有些是 200 OK (from memory cache)有些会是 200 OK (from disk cache)都差不多，只是从客户端取的位置不一样而已。除了给静态文件做 200 OK (from cache)缓存外，其实我们也可以给某些页面做，比如一些不经常改变内容的 ajax 页面。</p>
<h3 id="协商缓存-304-Not-Modified"><a href="#协商缓存-304-Not-Modified" class="headerlink" title="协商缓存 304 Not Modified"></a>协商缓存 304 Not Modified</h3><p>向服务器发送请求，服务器会根据这个请求的 Request Headers 的一些参数(etag 和 last-modified)来判断是否命中协商缓存，如果命中，则返回 304 状态码, 并带上新的 Request Headers 通知浏览器从缓存中读取资源；</p>
<p>协商缓存主要表现在 Response Headers 中的 etag 和 last-modified：</p>
<p><img src="https://yangyunhaiimagesoss.oss-cn-shanghai.aliyuncs.com/2011091750_1604915447310.jpg"></p>
<h3 id="强缓存和协商缓存的-header-参数"><a href="#强缓存和协商缓存的-header-参数" class="headerlink" title="强缓存和协商缓存的 header 参数"></a>强缓存和协商缓存的 header 参数</h3><p><code>Expires</code>：过期时间，如果设置了时间，则浏览器会在设置的时间内直接读取缓存，不再请求<br><code>Cache-Control</code>：当值设为 max-age=300 时，则代表在这个请求正确返回时间（浏览器也会记录下来）的 5 分钟内再次加载资源，就会命中强缓存。<br><code>cache-control</code>：除了该字段外，还有下面几个比较常用的设置值：</p>
<pre><code>（1） max-age：用来设置资源（representations）可以被缓存多长时间，单位为秒；

（2） s-maxage：和max-age是一样的，不过它只针对代理服务器缓存而言；

（3）public：指示响应可被任何缓存区缓存；

（4）private：只能针对个人用户，而不能被代理服务器缓存；

（5）no-cache：强制客户端直接向服务器发送请求,也就是说每次请求都必须向服务器发送。服务器接收到     请求，然后判断资源是否变更，是则返回新内容，否则返回304，未变更。这个很容易让人产生误解，使人误     以为是响应不被缓存。实际上Cache-Control:     no-cache是会被缓存的，只不过每次在向客户端（浏览器）提供响应数据时，缓存都要向服务器评估缓存响应的有效性。

（6）no-store：禁止一切缓存（这个才是响应不被缓存的意思）。</code></pre>
<h3 id="13-xss攻击和csrf攻击？"><a href="#13-xss攻击和csrf攻击？" class="headerlink" title="13. xss攻击和csrf攻击？"></a>13. <code>xss</code>攻击和<code>csrf</code>攻击？</h3><h3 id="什么是-XSS-攻击？"><a href="#什么是-XSS-攻击？" class="headerlink" title="什么是 XSS 攻击？"></a>什么是 XSS 攻击？</h3><p><code>XSS</code>是跨站脚本攻击<code>(Cross Site Scripting)</code>，为不和层叠样式表<code>(Cascading Style Sheets, CSS)</code>的缩写混淆，故将跨站脚本攻击缩写为<code>XSS</code>。</p>
<p>恶意攻击者往 Web 页面里插入恶意 Script 代码，当用户浏览该页之时，嵌入其中 Web 里面的 Script 代码会被执行，从而达到恶意攻击用户的目的。</p>
<h3 id="XSS-的危害"><a href="#XSS-的危害" class="headerlink" title="XSS 的危害?"></a>XSS 的危害?</h3><h4 id="1-窃取网页浏览中的-cookie-值"><a href="#1-窃取网页浏览中的-cookie-值" class="headerlink" title="1.窃取网页浏览中的 cookie 值"></a>1.窃取网页浏览中的 cookie 值</h4><p>在网页浏览中我们常常涉及到用户登录，登录完毕之后服务端会返回一个 cookie 值。这个 cookie 值相当于一个令牌，拿着这张令牌就等同于证明了你是某个用户。</p>
<p>如果你的 cookie 值被窃取，那么攻击者很可能能够直接利用你的这张令牌不用密码就登录你的账户。如果想要通过 script 脚本获得当前页面的 cookie 值，通常会用到 document.cookie。</p>
<p>试想下如果像空间说说中能够写入 xss 攻击语句，那岂不是看了你说说的人的号你都可以登录（不过某些厂商的 cookie 有其他验证措施如：Http-Only 保证同一 cookie 不能被滥用）</p>
<h4 id="2-劫持流量实现恶意跳转"><a href="#2-劫持流量实现恶意跳转" class="headerlink" title="2.劫持流量实现恶意跳转"></a>2.劫持流量实现恶意跳转</h4><p>这个很简单，就是在网页中想办法插入一句像这样的语句：</p>
<pre><code>&lt;script&gt;
window.location.href=&quot;http://www.baidu.com&quot;;
&lt;/script&gt;</code></pre>
<p>那么所访问的网站就会被跳转到百度的首页。</p>
<h3 id="XSS-攻击大致上分为两类"><a href="#XSS-攻击大致上分为两类" class="headerlink" title="XSS 攻击大致上分为两类?"></a>XSS 攻击大致上分为两类?</h3><ul>
<li>一类是反射型 XSS，又称非持久型 XSS，</li>
<li>一类是储存型 XSS，也就是持久型 XSS。</li>
</ul>
<h3 id="反射型-XSS"><a href="#反射型-XSS" class="headerlink" title="反射型 XSS?"></a>反射型 XSS?</h3><p>也就是攻击相对于访问者而言是一次性的，具体表现在我们把我们的恶意脚本通过 url 的方式传递给了服务器，而服务器则只是不加处理的把脚本“反射”回访问者的浏览器而使访问者的浏览器执行相应的脚本。</p>
<p>也就是说想要触发漏洞，需要访问特定的链接才能够实现。</p>
<h3 id="储存型-XSS"><a href="#储存型-XSS" class="headerlink" title="储存型 XSS?"></a>储存型 XSS?</h3><p>它与反射型 XSS 最大的不同就是服务器再接收到我们的恶意脚本时会将其做一些处理。</p>
<p>例如储存到数据库中，然后当我们再次访问相同页面时，将恶意脚本从数据库中取出并返回给浏览器执行。这就意味着只要访问了这个页面的访客，都有可能会执行这段恶意脚本，因此储存型 XSS 的危害会更大。</p>
<p>还记得在文章开头提到的留言板的例子吗？那通常就是储存型 XSS。当有人在留言内容中插入恶意脚本时，由于服务器要像每一个访客展示之前的留言内容，所以后面的访客自然会接收到之前留言中的恶意脚本而不幸躺枪。</p>
<p>这个过程一般而言只要用户访问这个界面就行了，不像反射型 XSS，需要访问特定的 URL。</p>
<h2 id="什么是-csrf-攻击"><a href="#什么是-csrf-攻击" class="headerlink" title="什么是 csrf 攻击?"></a>什么是 csrf 攻击?</h2><p>这也是一种常见的网站攻击手段，它主要利用的是我们网站对于用户的信任。</p>
<p><strong>什么意思呢？</strong>简单讲就是你刚刚登陆了腾讯充值中心，登陆充钱完了，你就关掉网站了，换了另外一个网站<code>www.qq.com</code>。</p>
<p>然后这个网站里面有个图片或者是超链接，这个 url 是<code>www.qq.com/chongzhizhongxin/pay?accout=xiaomizhou&amp;number=10000</code>；（我们假设这是 qq 充值中心对于充值的 api 接口，现实中肯定不是这样也没有这么简单）。只要你点击了这个按钮，你就会向小米粥账户充值 10000 个 q 币了。</p>
<h4 id="为什么能够这样呢？"><a href="#为什么能够这样呢？" class="headerlink" title="为什么能够这样呢？"></a>为什么能够这样呢？</h4><p>因为你刚刚登陆过 qq 充值系统不久，登陆状态还没有消失，信息都还在，所以能够直接调用接口进行支付。在这个过程中，黑客没办法知道你的用户信息，支付密码，甚至你的账户。但是凭借着 qq 充值网站对于用户的信任，以为这是你本人的操作，所以执行了。</p>
<h4 id="那么怎么防御呢？"><a href="#那么怎么防御呢？" class="headerlink" title="那么怎么防御呢？"></a>那么怎么防御呢？</h4><p>只要我们开发人员，在一些重要的接口上设置一个验证过程，而这个验证是需要在 qq 充值中心网页的一个随机码（可以是时间戳加密），然后通过一系列的加密才能够获得。</p>
<p>而 csrf 攻击是在<code>www.qq.com</code>上发布出来的，没有进入到 qq 充值中心，所以无法获得这个随机数，从而调用接口的时候这个部分的信息为空或者错误，然后调用失败。</p>
<h4 id="14-如何进行网站性能优化？"><a href="#14-如何进行网站性能优化？" class="headerlink" title="14.如何进行网站性能优化？"></a>14.如何进行网站性能优化？</h4><h3 id="一、减少请求资源大小或者次数"><a href="#一、减少请求资源大小或者次数" class="headerlink" title="一、减少请求资源大小或者次数"></a>一、减少请求资源大小或者次数</h3><p>1、尽量和并和压缩 css 和 js 文件。（将 css 文件和并为一个。将 js 合并为一个）</p>
<blockquote>
<p>原因：主要是为了减少 http 请求次数以及减少请求资源的大小打包工具：webpack</p>
</blockquote>
<p>2、尽量所使用的字体图标或者 SVG 图标来代替传统 png 图,因为字体图标或者 SVG 是矢量图，代码编写出来的，方大不会变形，而且渲染速度快</p>
<p>3、采用图片的懒加载（延迟加载）,目的为了，减少页面第一次加载过程中 http 的请求次数</p>
<h4 id="具体步骤："><a href="#具体步骤：" class="headerlink" title="具体步骤："></a>具体步骤：</h4><p>1、页面开始加载时不去发送 http 请求，而是放置一张占位图</p>
<p>2、当页面加载完时，并且图片在可视区域再去请求加载图片信息</p>
<p>4、能用 css 做的效果，不要用 js 做，能用原生 js 做的，不要轻易去使用第三方插件。</p>
<h4 id="避免引入第三方大量的库。而自己却只是用里面的一个小功能"><a href="#避免引入第三方大量的库。而自己却只是用里面的一个小功能" class="headerlink" title="避免引入第三方大量的库。而自己却只是用里面的一个小功能"></a>避免引入第三方大量的库。而自己却只是用里面的一个小功能</h4><p>5、使用雪碧图或者是说图片精灵 把所有相对较小的资源图片，绘制在一张大图上，只需要将大图下载下来，然后利用 图片定位来讲小图展现在页面中（background-position:百分比，数值）</p>
<p>6、减少对 cookie 的使用（最主要的就是减少本地 cookie 存储内容的大小），因为客户端操作 cookie 的时候，这些信息总是在客户端和服务端传递。如果上设置不当，每次发送一个请求将会携带 cookie</p>
<p>7、前端与后端进行数据交互时，对于多项数据尽可能基于 json 格式来进行传送。相对于使用 xml 来说传输有这个优势</p>
<h4 id="目的：是数据处理方便，资源偏小"><a href="#目的：是数据处理方便，资源偏小" class="headerlink" title="目的：是数据处理方便，资源偏小"></a>目的：是数据处理方便，资源偏小</h4><p>8、前端与后端协商，合理使用 keep-alive</p>
<p>9、前端与服务器协商，使用响应资源的压缩</p>
<p>10、避免使用 iframe 不仅不好管控样式，而且相当于在本页面又嵌套其他页面，消耗性能会更大。因为还回去加载这个嵌套页面的资源</p>
<p>11、在基于 ajax 的 get 请求进行数据交互的时候，根据需求可以让其产生缓存（注意:这个 缓存不是我们常看到的 304 状态码，去浏览器本地取数据），这样在下一次从相同地址获取是数据 时，取得就是上一次缓存的数据。（注意：很少使用，一般都会清空。根据需求来做）</p>
<h3 id="二、代码优化相关"><a href="#二、代码优化相关" class="headerlink" title="二、代码优化相关"></a>二、代码优化相关</h3><p>1、在 js 中尽量减少闭包的使用 原因：使用闭包后，闭包所在的上下文不会被释放</p>
<p>2、减少对 DOM 操作，主要是减少 DOM 的重绘与回流（重排）</p>
<blockquote>
<p>关于重排（回流）的分离读写：如果需要设置多个样式，把设置样式全放在一起设置，不要一条一条的设置。使用文档碎片或者字符串拼接做数据绑定（DOM 的动态创建）</p>
</blockquote>
<p>3、在 js 中避免嵌套循环和”死循环”(一旦遇到死循环，浏览器就会直接卡掉)</p>
<p>4、把 css 放在 body 上，把 js 放在 body 下面 让其先加载 css（注意：这里关于优化没有多大关系）</p>
<p>5、减少 css 表达式的使用</p>
<p>6、css 选择器解析规则所示从右往左解析的。减少元素标签作为对后一个选择对象</p>
<p>7、尽量将一个动画元素单独设置为一个图层（避免重绘或者回流的大小）</p>
<blockquote>
<p>注意：图层不要过多设置，否则不但效果没有达到反而更差了</p>
</blockquote>
<p>8、在 js 封装过程中，尽量做到低耦合高内聚。减少页面的冗余代码</p>
<p>9、css 中设置定位后，最好使用 z-index 改变盒子的层级，让盒子不在相同的平面上</p>
<p>10、css 导入的时候尽量减少@import 导入式，因为@import 是同步操作，只有把对应的样式导入后，才会继续向下加兹安，而 link 是异步的操作</p>
<p>11、使用 window.requestAnimationFrame(js 的帧动画)代替传统的定时器动画 如果想使用每隔一段时间执行动画，应该避免使用 setInterval</p>
<blockquote>
<p>尽量使用 setTimeout 代替 setInterval 定时器。因为 setInterval 定时器存在弊端：可能造成两个动画间隔时间缩短</p>
</blockquote>
<p>12、尽量减少使用递归。避免死递归 解决：建议使用尾递归</p>
<p>13、基于 script 标签下载 js 文件时，可以使用 defer 或者 async 来异步加载</p>
<p>14、在事件绑定中，尽可能使用事件委托，减少循环给 DOM 元素绑定事件处理函数。</p>
<p>15、在 js 封装过程中，尽量做到低耦合高内聚。减少页面的冗余代码</p>
<p>16、减少 Flash 的使用</p>
<h3 id="三、存储"><a href="#三、存储" class="headerlink" title="三、存储"></a>三、存储</h3><p>1、结合后端，利用浏览器的缓存技术，做一些缓存（让后端返回 304，告诉浏览器去本地拉取数据）。（注意：也有弊端）可以让一些不太会改变的静态资源做缓存。比如：一些图片，js，cs</p>
<p>2、利用 h5 的新特性（localStorage、sessionStorage）做一些简单数据的存储， 避免向后台请求数据或者说在离线状态下做一些数据展示。</p>
<h3 id="四、其他优化"><a href="#四、其他优化" class="headerlink" title="四、其他优化"></a>四、其他优化</h3><p>1、避免使用 iframe 不仅不好管控样式，而且相当于在本页面又嵌套其他页面，消耗性能会更大。因为还回去加载这个嵌套页面的资源</p>
<p>2、页面中的是数据获取采用异步编程和延迟分批加载，使用异步加载是数据主要是为了避免浏览器失去响应。如果你使用同步，加载数据很大并且很慢</p>
<p>那么，页面会在一段时间内处于阻塞状态。目的：为了解决请求数据不耽搁渲染，提高页面的 渲染效率。</p>
<h4 id="解决方法："><a href="#解决方法：" class="headerlink" title="解决方法："></a>解决方法：</h4><p>需要动态绑定的是数据区域先隐藏，等数据返回并且绑定后在让其显示延迟分批加载类似图片懒加载。</p>
<p>减少第一次页面加载时候的 http 请求次数</p>
<p>3、页面中出现音视频标签，我们不让页面加载的时候去加载这些资源（否则第一次加载会很慢）</p>
<p>解决方法：<br>只需要将音视频的 preload=none 即可。</p>
<p>目的：为了等待页面加载完成时，并且音视频要播放的时候去加兹安音视频资源</p>
<p>4、尽量将一个动画元素单独设置为一个图层（避免重绘或者回流的大小） 注意：图层不要过多设置，否则不但效果没有达到反而更差了</p>

                
            </div>
            <hr/>

            



            <div class="tag_share" style="display: block;">
                <div class="post-meta__tag-list" style="display: inline-block;">
                    
                        <div class="article-tag">
                            
                                <a href="/pride-blog/tags/%E6%AF%8F%E5%A4%A9%E4%B8%80%E4%B8%AA%E7%A6%BB%E8%81%8C%E5%B0%8F%E6%8A%80%E5%B7%A7/">
                                    <span class="chip bg-color">每天一个离职小技巧</span>
                                </a>
                            
                        </div>
                    
                </div>
                <div class="post_share" style="zoom: 80%; width: fit-content; display: inline-block; float: right; margin: -0.15rem 0;">
                    <link rel="stylesheet" type="text/css" href="/pride-blog/libs/share/css/share.min.css">
<div id="article-share">

    

    

</div>

                </div>
            </div>
            
        </div>
    </div>

    

    

    

    

    

    

    

    

    

<article id="prenext-posts" class="prev-next articles">
    <div class="row article-row">
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge left-badge text-color">
                <i class="fas fa-chevron-left"></i>&nbsp;上一篇</div>
            <div class="card">
                <a href="/pride-blog/2021/080441514.html">
                    <div class="card-image">
                        
                        
                        <img src="/pride-blog/medias/featureimages/8.jpg" class="responsive-img" alt="CSS3">
                        
                        <span class="card-title">CSS3</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                            
                        
                    </div>
                    <div class="publish-info">
                        <span class="publish-date">
                            <i class="far fa-clock fa-fw icon-date"></i>2021-08-04
                        </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-bookmark fa-fw icon-category"></i>
                            
                            <a href="/pride-blog/categories/%E6%AF%8F%E5%A4%A9%E4%B8%80%E4%B8%AA%E7%A6%BB%E8%81%8C%E5%B0%8F%E6%8A%80%E5%B7%A7/" class="post-category">
                                    每天一个离职小技巧
                                </a>
                            
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/pride-blog/tags/%E6%AF%8F%E5%A4%A9%E4%B8%80%E4%B8%AA%E7%A6%BB%E8%81%8C%E5%B0%8F%E6%8A%80%E5%B7%A7/">
                        <span class="chip bg-color">每天一个离职小技巧</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge right-badge text-color">
                下一篇&nbsp;<i class="fas fa-chevron-right"></i>
            </div>
            <div class="card">
                <a href="/pride-blog/2021/080341513.html">
                    <div class="card-image">
                        
                        
                        <img src="/pride-blog/medias/featureimages/17.jpg" class="responsive-img" alt="Vue源码系列5-hookEvents">
                        
                        <span class="card-title">Vue源码系列5-hookEvents</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                            
                        
                    </div>
                    <div class="publish-info">
                            <span class="publish-date">
                                <i class="far fa-clock fa-fw icon-date"></i>2021-08-03
                            </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-bookmark fa-fw icon-category"></i>
                            
                            <a href="/pride-blog/categories/Vue%E6%BA%90%E7%A0%81/" class="post-category">
                                    Vue源码
                                </a>
                            
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/pride-blog/tags/Vue%E6%BA%90%E7%A0%81/">
                        <span class="chip bg-color">Vue源码</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
    </div>
</article>

</div>



<!-- 代码块功能依赖 -->
<script type="text/javascript" src="/pride-blog/libs/codeBlock/codeBlockFuction.js"></script>

<!-- 代码语言 -->

<script type="text/javascript" src="/pride-blog/libs/codeBlock/codeLang.js"></script>


<!-- 代码块复制 -->

<script type="text/javascript" src="/pride-blog/libs/codeBlock/codeCopy.js"></script>


<!-- 代码块收缩 -->

<script type="text/javascript" src="/pride-blog/libs/codeBlock/codeShrink.js"></script>


    </div>
    <div id="toc-aside" class="expanded col l3 hide-on-med-and-down">
        <div class="toc-widget card" style="background-color: white;">
            <div class="toc-title"><i class="far fa-list-alt"></i>&nbsp;&nbsp;目录</div>
            <div id="toc-content"></div>
        </div>
    </div>
</div>

<!-- TOC 悬浮按钮. -->

<div id="floating-toc-btn" class="hide-on-med-and-down">
    <a class="btn-floating btn-large bg-color">
        <i class="fas fa-list-ul"></i>
    </a>
</div>


<script src="/pride-blog/libs/tocbot/tocbot.min.js"></script>
<script>
    $(function () {
        tocbot.init({
            tocSelector: '#toc-content',
            contentSelector: '#articleContent',
            headingsOffset: -($(window).height() * 0.4 - 45),
            collapseDepth: Number('0'),
            headingSelector: 'h2, h3, h4'
        });

        // modify the toc link href to support Chinese.
        let i = 0;
        let tocHeading = 'toc-heading-';
        $('#toc-content a').each(function () {
            $(this).attr('href', '#' + tocHeading + (++i));
        });

        // modify the heading title id to support Chinese.
        i = 0;
        $('#articleContent').children('h2, h3, h4').each(function () {
            $(this).attr('id', tocHeading + (++i));
        });

        // Set scroll toc fixed.
        let tocHeight = parseInt($(window).height() * 0.4 - 64);
        let $tocWidget = $('.toc-widget');
        $(window).scroll(function () {
            let scroll = $(window).scrollTop();
            /* add post toc fixed. */
            if (scroll > tocHeight) {
                $tocWidget.addClass('toc-fixed');
            } else {
                $tocWidget.removeClass('toc-fixed');
            }
        });

        
        /* 修复文章卡片 div 的宽度. */
        let fixPostCardWidth = function (srcId, targetId) {
            let srcDiv = $('#' + srcId);
            if (srcDiv.length === 0) {
                return;
            }

            let w = srcDiv.width();
            if (w >= 450) {
                w = w + 21;
            } else if (w >= 350 && w < 450) {
                w = w + 18;
            } else if (w >= 300 && w < 350) {
                w = w + 16;
            } else {
                w = w + 14;
            }
            $('#' + targetId).width(w);
        };

        // 切换TOC目录展开收缩的相关操作.
        const expandedClass = 'expanded';
        let $tocAside = $('#toc-aside');
        let $mainContent = $('#main-content');
        $('#floating-toc-btn .btn-floating').click(function () {
            if ($tocAside.hasClass(expandedClass)) {
                $tocAside.removeClass(expandedClass).hide();
                $mainContent.removeClass('l9');
            } else {
                $tocAside.addClass(expandedClass).show();
                $mainContent.addClass('l9');
            }
            fixPostCardWidth('artDetail', 'prenext-posts');
        });
        
    });
</script>

    

</main>




    <footer class="page-footer bg-color">
    

    <div class="container row center-align"
         style="margin-bottom: 0px !important;">
        <div class="col s12 m8 l8 copy-right">
            Copyright&nbsp;&copy;
            
                <span id="year">2021-2023</span>
            
            <span id="year">2021</span>
            <a href="/pride-blog/about" target="_blank">zihao xiong</a>
            |&nbsp;Powered by&nbsp;<a href="https://hexo.io/" target="_blank">Hexo</a>
            |&nbsp;Theme&nbsp;<a href="https://github.com/blinkfox/hexo-theme-matery" target="_blank">Matery</a>
            <br>
            
            
            
            
            
            <br>

            <!-- 运行天数提醒. -->
            
            <br>
            
        </div>
        <div class="col s12 m4 l4 social-link ">














</div>
    </div>
</footer>

<div class="progress-bar"></div>


    <!-- 搜索遮罩框 -->
<div id="searchModal" class="modal">
    <div class="modal-content">
        <div class="search-header">
            <span class="title"><i class="fas fa-search"></i>&nbsp;&nbsp;搜索</span>
            <input type="search" id="searchInput" name="s" placeholder="请输入搜索的关键字"
                   class="search-input">
        </div>
        <div id="searchResult"></div>
    </div>
</div>

<script type="text/javascript">
$(function () {
    var searchFunc = function (path, search_id, content_id) {
        'use strict';
        $.ajax({
            url: path,
            dataType: "xml",
            success: function (xmlResponse) {
                // get the contents from search data
                var datas = $("entry", xmlResponse).map(function () {
                    return {
                        title: $("title", this).text(),
                        content: $("content", this).text(),
                        url: $("url", this).text()
                    };
                }).get();
                var $input = document.getElementById(search_id);
                var $resultContent = document.getElementById(content_id);
                $input.addEventListener('input', function () {
                    var str = '<ul class=\"search-result-list\">';
                    var keywords = this.value.trim().toLowerCase().split(/[\s\-]+/);
                    $resultContent.innerHTML = "";
                    if (this.value.trim().length <= 0) {
                        return;
                    }
                    // perform local searching
                    datas.forEach(function (data) {
                        var isMatch = true;
                        var data_title = data.title.trim().toLowerCase();
                        var data_content = data.content.trim().replace(/<[^>]+>/g, "").toLowerCase();
                        var data_url = data.url;
                        data_url = data_url.indexOf('/') === 0 ? data.url : '/' + data_url;
                        var index_title = -1;
                        var index_content = -1;
                        var first_occur = -1;
                        // only match artiles with not empty titles and contents
                        if (data_title !== '' && data_content !== '') {
                            keywords.forEach(function (keyword, i) {
                                index_title = data_title.indexOf(keyword);
                                index_content = data_content.indexOf(keyword);
                                if (index_title < 0 && index_content < 0) {
                                    isMatch = false;
                                } else {
                                    if (index_content < 0) {
                                        index_content = 0;
                                    }
                                    if (i === 0) {
                                        first_occur = index_content;
                                    }
                                }
                            });
                        }
                        // show search results
                        if (isMatch) {
                            str += "<li><a href='" + data_url + "' class='search-result-title'>" + data_title + "</a>";
                            var content = data.content.trim().replace(/<[^>]+>/g, "");
                            if (first_occur >= 0) {
                                // cut out 100 characters
                                var start = first_occur - 20;
                                var end = first_occur + 80;
                                if (start < 0) {
                                    start = 0;
                                }
                                if (start === 0) {
                                    end = 100;
                                }
                                if (end > content.length) {
                                    end = content.length;
                                }
                                var match_content = content.substr(start, end);
                                // highlight all keywords
                                keywords.forEach(function (keyword) {
                                    var regS = new RegExp(keyword, "gi");
                                    match_content = match_content.replace(regS, "<em class=\"search-keyword\">" + keyword + "</em>");
                                });

                                str += "<p class=\"search-result\">" + match_content + "...</p>"
                            }
                            str += "</li>";
                        }
                    });
                    str += "</ul>";
                    $resultContent.innerHTML = str;
                });
            }
        });
    };

    searchFunc('/pride-blog/search.xml', 'searchInput', 'searchResult');
});
</script>

    <!-- 回到顶部按钮 -->
<div id="backTop" class="top-scroll">
    <a class="btn-floating btn-large waves-effect waves-light" href="#!">
        <i class="fas fa-arrow-up"></i>
    </a>
</div>


    <script src="/pride-blog/libs/materialize/materialize.min.js"></script>
    <script src="/pride-blog/libs/masonry/masonry.pkgd.min.js"></script>
    <script src="/pride-blog/libs/aos/aos.js"></script>
    <script src="/pride-blog/libs/scrollprogress/scrollProgress.min.js"></script>
    <script src="/pride-blog/libs/lightGallery/js/lightgallery-all.min.js"></script>
    <script src="/pride-blog/js/matery.js"></script>

    <!-- Baidu Analytics -->

    <!-- Baidu Push -->

<script>
    (function () {
        var bp = document.createElement('script');
        var curProtocol = window.location.protocol.split(':')[0];
        if (curProtocol === 'https') {
            bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
        } else {
            bp.src = 'http://push.zhanzhang.baidu.com/push.js';
        }
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(bp, s);
    })();
</script>

    
    <script src="/pride-blog/libs/others/clicklove.js" async="async"></script>
    
    

    

    

    <!--腾讯兔小巢-->
    
    
    <script type="text/javascript" color="0,0,255"
        pointColor="0,0,255" opacity='0.7'
        zIndex="-1" count="99"
        src="/pride-blog/libs/background/canvas-nest.js"></script>
    

    
    
    <script type="text/javascript" size="150" alpha='0.6'
        zIndex="-1" src="/pride-blog/libs/background/ribbon-refresh.min.js" async="async"></script>
    

    
    <script type="text/javascript" src="/pride-blog/libs/background/ribbon-dynamic.js" async="async"></script>
    

    
    <script src="/pride-blog/libs/instantpage/instantpage.js" type="module"></script><!-- hexo-inject:begin --><!-- hexo-inject:end -->
    

</body>
<script src="./../source/js/cursor.js"></script>

</html>
